//使用indexDB模拟实现存储库模式
interface BaseEntity {
    id: string;
    propertyName: string;
    address: {
        [key: string]: any;
    };
    numberOfUnits: number;
    propertyManager: {
        [key: string]: any;
    };
    monthlyRent: number;
    status: string;
}

interface DetailEntity extends BaseEntity {
    propertyDetails: object;
}

export type EntityUnionType = BaseEntity | DetailEntity

interface IRepository<T = EntityUnionType> {
    dbPromise: Promise<unknown>;
    currentTable: string;
    getByIndex: (index: IDBValidKey) =>Promise<T>;
    insert: (index: IDBValidKey, data: T) => void
    getList: () => Promise<Array<T>>
}

function promisify(request: IDBOpenDBRequest | IDBRequest<IDBValidKey> | IDBRequest<any[]>) {
    return new Promise((resolve, reject) => {
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
}
/**
 * 根据需求只简单实现了增和改
 * @param name 当前需要操作的实体/表名
 */

class Repository implements IRepository {
    dbPromise: Promise<unknown>;
    currentTable: string;

    constructor(name: string) {
        const request = window.indexedDB.open('examine_demo');
        request.onupgradeneeded = () => {
            const db = request.result
            for (let item of ['property', 'property_detail']) {
                if (!db.objectStoreNames.contains(item)) {
                    db.createObjectStore(item)
                }
            }
        }
        this.dbPromise = promisify(request);
        this.currentTable = name
    }
    async getTable(operationMode: IDBTransactionMode, currentTable = this.currentTable) {
        const db: IDBDatabase = await this.dbPromise as IDBDatabase;
        return db.transaction(currentTable, operationMode).objectStore(currentTable);
    }
    /**
 * 根据实体/表名获取全部数据
 * @returns 
 */
    async getList() {
        const table = await this.getTable('readonly')
        const data = await promisify(table.getAll()) as Array<EntityUnionType>
        return data
    }
    /**
     * 根据索引获取数据
     * @param id 
     * @returns 
     */
    async getByIndex(index: IDBValidKey) {
        const table = await this.getTable('readonly')
        const data = await promisify(table.get(index)) as EntityUnionType
        return data
    }
    /**
     * 插入数据
     * @param value 
     */
    async insert(index: IDBValidKey, value: EntityUnionType) {
        const table = await this.getTable('readwrite')
        promisify(table.put(value, index))
    }
}


export default Repository